#include "grid.h"

Grid::Grid(int r, int c) : rows(r), cols(c), cells(r*c, 0), diagonal(false), start{0,0}, goal{r-1,c-1} {}

bool Grid::in_bounds(Pos p) const { return p.r>=0 && p.c>=0 && p.r<rows && p.c<cols; }

bool Grid::is_blocked(Pos p) const { return cells[p.r*cols + p.c] != 0; }

void Grid::set_block(Pos p, bool blocked) { cells[p.r*cols + p.c] = blocked ? 1 : 0; }

std::vector<Pos> Grid::neighbors(Pos p) const {
    static const int d4[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
    static const int d8[8][2] = {{1,0},{-1,0},{0,1},{0,-1},{1,1},{1,-1},{-1,1},{-1,-1}};
    std::vector<Pos> ns;
    if (diagonal) {
        for (auto d : d8) {
            Pos q{p.r + d[0], p.c + d[1]};
            if (in_bounds(q) && !is_blocked(q)) ns.push_back(q);
        }
    } else {
        for (auto d : d4) {
            Pos q{p.r + d[0], p.c + d[1]};
            if (in_bounds(q) && !is_blocked(q)) ns.push_back(q);
        }
    }
    return ns;
}

